using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Gko.Wpf.Mvvm.Interfaces;

namespace Gko.Wpf.Mvvm
{
	public abstract class ViewModelServiceBase<TViewModelId> : IViewModelService<TViewModelId> where TViewModelId : IEquatable<TViewModelId>
	{
		private readonly IViewModelContext context;
		private readonly Dictionary<TViewModelId, Type> viewModelTypes;
		protected ViewModelServiceBase(IViewModelContext context)
		{
			this.context = context;
			this.viewModelTypes = new Dictionary<TViewModelId, Type>();
		}

		protected IViewModelContext Context
		{
			get
			{
				return this.context;
			}
		}

		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
		public void RegisterViewModel<TViewModel>(TViewModelId viewModelId) where TViewModel : IViewModel
		{
			this.viewModelTypes[viewModelId] = typeof(TViewModel);
		}

		/// <exception cref="InvalidOperationException"><c>InvalidOperationException</c>.</exception>
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)")]
		public IViewModel CreateViewModel(TViewModelId viewModelId, params object[] arguments)
		{
			Type viewModelType;
			if(!this.viewModelTypes.TryGetValue(viewModelId, out viewModelType)) {
				throw new InvalidOperationException(String.Format("View model id [{0}] is not registered", viewModelId));
			}
			return (IViewModel)Activator.CreateInstance(viewModelType, arguments);
		}
	}
}